﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;

namespace BookShelf.Model.Tests
{
    /// <summary>
    /// Summary description for BookTest
    /// </summary>
    [TestClass]
    public class BookTest
    {

        private int bookID = 0;
        private string isbn = "0123456789";
        private string title = "A Book Title";
        private DateTime publicationDate = DateTime.Today;  //Invalid PublicationDate
        private int pages = 25;

        public BookTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestBookConstructor()
        {

            Book book = new Book(bookID, isbn, title, publicationDate, pages);

            Assert.AreEqual(book.ID, bookID);
            Assert.AreEqual(book.Isbn, isbn);
            Assert.AreEqual(book.Title, title);
            Assert.AreEqual(book.PublicationDate, publicationDate);
            Assert.AreEqual(book.Pages, pages);

        }

        [TestMethod, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestBookConstructorWithInvalidID()
        {
            Book book = new Book(-1, isbn, title, publicationDate, pages);
        }

        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void TestBookConstructorWithInvalidIsbn()
        {
            Book book = new Book(bookID, string.Empty, title, publicationDate, pages);
        }

        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void TestBookConstructorWithInvalidTitle()
        {
            Book book = new Book(bookID, isbn, string.Empty, publicationDate, pages);
        }

        [TestMethod, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestBookConstructorWithInvalidPublicationDate()
        {
            Book book = new Book(bookID, isbn, title, DateTime.MinValue, pages);
        }

        [TestMethod()]
        public void TestBookEquality()
        {

            Book book1 = new Book(bookID, isbn, title, publicationDate, pages);
            Book book2 = new Book(bookID, isbn, title, publicationDate, pages);

            Assert.IsTrue(book1.Equals(book2));

            book2 = new Book(bookID, "0000000000", title, publicationDate, pages);

            Assert.IsFalse(book1.Equals(book2));

        }
        
        [TestMethod]
        public void TestAddAuthorToBook()
        {
            Author author = new Author(1, "John", "", "Doe");
            Book book = new Book(bookID, isbn, title, publicationDate, pages);

            book.AddAuthor(author);

            Assert.AreEqual(book.Authors.Count, 1);
            Assert.AreEqual(book.Authors[0], author);
        }

        [TestMethod]
        public void TestRemoveAuthorToBook()
        {
            Author author1 = new Author(1, "John", "", "Doe");
            Author author2 = new Author(2, "James", "", "Smith");
            Book book = new Book(bookID, isbn, title, publicationDate, pages);

            book.AddAuthor(author1);
            book.AddAuthor(author2);

            Assert.AreEqual(book.Authors.Count, 2);

            Assert.IsTrue(book.RemoveAuthor(author1));
            Assert.AreEqual(book.Authors.Count, 1);

        }

    }
}
